home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / SpriteFight 2002 v2.0a1 / SpriteWorld.c < prev    next >
Text File  |  1995-12-26  |  37KB  |  1,319 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteWorld.c
  3. //
  4. //    Created:    Wednesday, May 29, 1991 at 10:43:28 PM
  5. //    By:        Tony Myles
  6. //
  7. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  8. //
  9. //    Description:    implementation of the sprite world architecture
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __QUICKDRAW__
  18. #include <QuickDraw.h>
  19. #endif
  20.  
  21. #ifndef __MEMORY__
  22. #include <Memory.h>
  23. #endif
  24.  
  25. #ifndef __GESTALTEQU__
  26. #include <GestaltEqu.h>
  27. #endif
  28.  
  29. #ifndef __SPRITEWORLDUTILS__
  30. #include "SpriteWorldUtils.h"
  31. #endif
  32.  
  33. #ifndef __SPRITEWORLD__
  34. #include "SpriteWorld.h"
  35. #endif
  36.  
  37. #ifndef __SPRITELAYER__
  38. #include "SpriteLayer.h"
  39. #endif
  40.  
  41. #ifndef __SPRITE__
  42. #include "Sprite.h"
  43. #endif
  44.  
  45. #ifndef __FRAME__
  46. #include "Frame.h"
  47. #endif
  48.  
  49. #ifndef __BLITPIXIE__
  50. #include "BlitPixie.h"
  51. #endif
  52.  
  53. #if MPW
  54. #pragma segment SpriteWorld
  55. #endif
  56.  
  57. char gSWmmuMode;
  58.  
  59.  
  60. ///--------------------------------------------------------------------------------------
  61. //    SWEnterSpriteWorld
  62. ///--------------------------------------------------------------------------------------
  63.  
  64. SW_FUNC OSErr SWEnterSpriteWorld(void)
  65. {
  66.     OSErr err;
  67.     long    versionNumber;
  68.  
  69.         // make sure we can run in this environment
  70.     err = Gestalt(gestaltTimeMgrVersion, &versionNumber);
  71.  
  72.     if ((err != noErr) || (versionNumber < gestaltStandardTimeMgr))
  73.     {
  74.         err = kTimeMgrNotPresentErr;
  75.     }
  76.  
  77.     if (err == noErr)
  78.     {
  79.         gSWmmuMode = GetMMUMode();
  80.     }
  81.  
  82.     return err;
  83. }
  84.  
  85.  
  86. ///--------------------------------------------------------------------------------------
  87. //    SWExitSpriteWorld
  88. ///--------------------------------------------------------------------------------------
  89.  
  90. SW_FUNC void SWExitSpriteWorld(void)
  91. {
  92.     // nothing happens here right now, but that might change later
  93. }
  94.  
  95.  
  96. ///--------------------------------------------------------------------------------------
  97. //    SWCreateSpriteWorld
  98. ///--------------------------------------------------------------------------------------
  99.  
  100. SW_FUNC OSErr SWCreateSpriteWorld(
  101.     SpriteWorldPtr *spriteWorldP,
  102.     FramePtr windowFrameP,
  103.     FramePtr backFrameP,
  104.     FramePtr loadFrameP)
  105. {
  106.     OSErr err;
  107.     SpriteWorldPtr tempSpriteWorldP;
  108.  
  109.     err = noErr;
  110.     *spriteWorldP = NULL;
  111.  
  112.     tempSpriteWorldP = (SpriteWorldPtr)NewPtrClear((Size)sizeof(SpriteWorldRec));
  113.  
  114.     if (tempSpriteWorldP != NULL)
  115.     {
  116.         tempSpriteWorldP->windowFrameP = windowFrameP;
  117.         tempSpriteWorldP->backFrameP = backFrameP;
  118.         tempSpriteWorldP->loadFrameP = loadFrameP;
  119.         tempSpriteWorldP->eraseDrawProc = SWStdWorldDrawProc;
  120.         tempSpriteWorldP->screenDrawProc = SWStdWorldDrawProc;
  121.  
  122.         *spriteWorldP = tempSpriteWorldP;
  123.     }
  124.     else
  125.     {
  126.         err = MemError();
  127.     }
  128.  
  129.     return err;
  130. }
  131.  
  132.  
  133. ///--------------------------------------------------------------------------------------
  134. //    SWCreateSpriteWorldFromWindow
  135. ///--------------------------------------------------------------------------------------
  136.  
  137. SW_FUNC OSErr SWCreateSpriteWorldFromWindow(
  138.     SpriteWorldPtr* spriteWorldP,
  139.     CWindowPtr srcWindowP,
  140.     Rect* worldRect)
  141. {
  142.     OSErr err;
  143.     CGrafPtr savePort;
  144.     FramePtr windowFrameP, backFrameP, loadFrameP;
  145.     Rect tempRect;
  146.  
  147.     *spriteWorldP = NULL;
  148.     windowFrameP = backFrameP = loadFrameP = NULL;
  149.  
  150.     tempRect = (worldRect == NULL) ? srcWindowP->portRect : *worldRect;
  151.  
  152.     GetPort((GrafPtr*)&savePort);
  153.     SetPort((GrafPtr)srcWindowP);
  154.  
  155.         // create window frame
  156.     err = SWCreateFrame(&windowFrameP, srcWindowP, &tempRect);
  157.  
  158.     if (err == noErr)
  159.     {
  160.             // create back drop frame
  161.         err = SWCreateFrame(&backFrameP, NULL, &tempRect);
  162.     }
  163.  
  164.     if (err == noErr)
  165.     {
  166.             // create loader frame
  167.         err = SWCreateFrame(&loadFrameP, NULL, &tempRect);
  168.     }
  169.  
  170.     if (err == noErr)
  171.     {
  172.             // create sprite world
  173.         err = SWCreateSpriteWorld(spriteWorldP, windowFrameP, backFrameP, loadFrameP);
  174.     }
  175.  
  176.     if (err != noErr)
  177.     {
  178.             // an error occurred so dispose of anything we managed to create
  179.  
  180.         if (windowFrameP != NULL)
  181.         {
  182.             SWDisposeFrame(windowFrameP);
  183.         }
  184.  
  185.         if (backFrameP != NULL)
  186.         {
  187.             SWDisposeFrame(backFrameP);
  188.         }
  189.  
  190.         if (loadFrameP != NULL)
  191.         {
  192.             SWDisposeFrame(loadFrameP);
  193.         }
  194.     }
  195.  
  196.     SetPort((GrafPtr)savePort);
  197.  
  198.     return err;
  199. }
  200.  
  201.  
  202. ///--------------------------------------------------------------------------------------
  203. //    SWDisposeSpriteWorld
  204. ///--------------------------------------------------------------------------------------
  205.  
  206. SW_FUNC void SWDisposeSpriteWorld(
  207.     SpriteWorldPtr spriteWorldP)
  208. {
  209.     if (spriteWorldP != NULL)
  210.     {
  211.         SWDisposeFrame(spriteWorldP->backFrameP);
  212.  
  213.         SWDisposeFrame(spriteWorldP->loadFrameP);
  214.  
  215.         spriteWorldP->windowFrameP->framePort.colorGrafP = NULL;
  216.         SWDisposeFrame(spriteWorldP->windowFrameP);
  217.  
  218.         DisposePtr((Ptr)spriteWorldP);
  219.     }
  220. }
  221.  
  222.  
  223. ///--------------------------------------------------------------------------------------
  224. //    SWAddSpriteLayer
  225. ///--------------------------------------------------------------------------------------
  226.  
  227. SW_FUNC void SWAddSpriteLayer(
  228.     SpriteWorldPtr spriteWorldP,
  229.     SpriteLayerPtr newSpriteLayerP)
  230. {
  231.     SpriteLayerPtr tailSpriteLayerP = spriteWorldP->tailSpriteLayerP;
  232.  
  233.     if (tailSpriteLayerP != NULL)
  234.     {
  235.             // doubly link the new layer
  236.         tailSpriteLayerP->nextSpriteLayerP = newSpriteLayerP;
  237.         newSpriteLayerP->prevSpriteLayerP = tailSpriteLayerP;
  238.         newSpriteLayerP->nextSpriteLayerP = NULL;
  239.     }    
  240.     else
  241.     {
  242.         newSpriteLayerP->prevSpriteLayerP = NULL;
  243.         newSpriteLayerP->nextSpriteLayerP = NULL;
  244.  
  245.             // make the new layer the head
  246.         spriteWorldP->headSpriteLayerP = newSpriteLayerP;
  247.     }
  248.  
  249.         // make the new layer the tail
  250.     spriteWorldP->tailSpriteLayerP = newSpriteLayerP;
  251. }
  252.  
  253.  
  254. ///--------------------------------------------------------------------------------------
  255. //    SWRemoveSpriteLayer
  256. ///--------------------------------------------------------------------------------------
  257.  
  258. SW_FUNC void SWRemoveSpriteLayer(
  259.     SpriteWorldPtr spriteWorldP,
  260.     SpriteLayerPtr oldSpriteLayerP)
  261. {
  262.         // is there a next layer?
  263.     if (oldSpriteLayerP->nextSpriteLayerP != NULL)
  264.     {
  265.             // link the next layer to the prev layer
  266.         oldSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
  267.     }
  268.     else
  269.     {
  270.             // make the prev layer the tail
  271.         spriteWorldP->tailSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
  272.     }
  273.  
  274.         // is there a prev layer?
  275.     if (oldSpriteLayerP->prevSpriteLayerP != NULL)
  276.     {
  277.             // link the prev layer to the next layer
  278.         oldSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
  279.     }
  280.     else
  281.     {
  282.             // make the next layer the head
  283.         spriteWorldP->headSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
  284.     }
  285. }
  286.  
  287.  
  288. ///--------------------------------------------------------------------------------------
  289. //    SWSwapSpriteLayer
  290. ///--------------------------------------------------------------------------------------
  291.  
  292. SW_FUNC void SWSwapSpriteLayer(
  293.     SpriteWorldPtr spriteWorldP,
  294.     SpriteLayerPtr srcSpriteLayerP,
  295.     SpriteLayerPtr dstSpriteLayerP)
  296. {
  297.     register SpriteLayerPtr swapSpriteLayerP;
  298.     
  299.     swapSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
  300.     srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
  301.     dstSpriteLayerP->nextSpriteLayerP = swapSpriteLayerP;
  302.  
  303.     swapSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
  304.     srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
  305.     dstSpriteLayerP->prevSpriteLayerP = swapSpriteLayerP;
  306.  
  307.     if (srcSpriteLayerP->nextSpriteLayerP == NULL)
  308.     {
  309.         spriteWorldP->tailSpriteLayerP = srcSpriteLayerP;
  310.     }
  311.     else if (srcSpriteLayerP->prevSpriteLayerP == NULL)
  312.     {
  313.         spriteWorldP->headSpriteLayerP = srcSpriteLayerP;
  314.     }
  315.  
  316.     if (dstSpriteLayerP->nextSpriteLayerP == NULL)
  317.     {
  318.         spriteWorldP->tailSpriteLayerP = dstSpriteLayerP;
  319.     }
  320.     else if (dstSpriteLayerP->prevSpriteLayerP == NULL)
  321.     {
  322.         spriteWorldP->headSpriteLayerP = dstSpriteLayerP;
  323.     }
  324. }
  325.  
  326.  
  327. ///--------------------------------------------------------------------------------------
  328. //    SWGetNextSpriteLayer
  329. ///--------------------------------------------------------------------------------------
  330.  
  331. SW_FUNC SpriteLayerPtr SWGetNextSpriteLayer(
  332.     SpriteWorldPtr spriteWorldP,
  333.     SpriteLayerPtr curSpriteLayerP)
  334. {
  335.     return (curSpriteLayerP == NULL) ?
  336.             spriteWorldP->headSpriteLayerP :
  337.             curSpriteLayerP->nextSpriteLayerP;
  338. }
  339.  
  340.  
  341. ///--------------------------------------------------------------------------------------
  342. //    SWLockSpriteWorld
  343. ///--------------------------------------------------------------------------------------
  344.  
  345. SW_FUNC void SWLockSpriteWorld(
  346.     SpriteWorldPtr spriteWorldP)
  347. {
  348.     SpriteLayerPtr curSpriteLayerP;
  349.  
  350.     SWLockFrame(spriteWorldP->windowFrameP);
  351.     SWLockFrame(spriteWorldP->backFrameP);
  352.     SWLockFrame(spriteWorldP->loadFrameP);
  353.  
  354.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  355.  
  356.     while (curSpriteLayerP != NULL)
  357.     {
  358.         SWLockSpriteLayer(curSpriteLayerP);
  359.  
  360.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  361.     }
  362. }
  363.  
  364.  
  365. ///--------------------------------------------------------------------------------------
  366. //    SWUnlockSpriteWorld
  367. ///--------------------------------------------------------------------------------------
  368.  
  369. SW_FUNC void SWUnlockSpriteWorld(
  370.     SpriteWorldPtr spriteWorldP)
  371. {
  372.     SpriteLayerPtr curSpriteLayerP;
  373.  
  374.     SWUnlockFrame(spriteWorldP->windowFrameP);
  375.     SWUnlockFrame(spriteWorldP->backFrameP);
  376.     SWUnlockFrame(spriteWorldP->loadFrameP);
  377.  
  378.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  379.  
  380.     while (curSpriteLayerP != NULL)
  381.     {
  382.         SWUnlockSpriteLayer(curSpriteLayerP);
  383.  
  384.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  385.     }
  386. }
  387.  
  388.  
  389. ///--------------------------------------------------------------------------------------
  390. //    SWSetPortToBackGround
  391. ///--------------------------------------------------------------------------------------
  392.  
  393. SW_FUNC void SWSetPortToBackGround(
  394.     SpriteWorldPtr spriteWorldP)
  395. {
  396.     SetPort(spriteWorldP->backFrameP->framePort.monoGrafP);
  397. }
  398.  
  399.  
  400. ///--------------------------------------------------------------------------------------
  401. //    SWSetPortToWindow
  402. ///--------------------------------------------------------------------------------------
  403.  
  404. SW_FUNC void SWSetPortToWindow(
  405.     SpriteWorldPtr spriteWorldP)
  406. {
  407.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  408. }
  409.  
  410.  
  411. ///--------------------------------------------------------------------------------------
  412. //    SWSetSpriteWorldEraseProc
  413. ///--------------------------------------------------------------------------------------
  414.  
  415. SW_FUNC void SWSetSpriteWorldEraseProc(
  416.     SpriteWorldPtr spriteWorldP,
  417.     WorldDrawProcPtr eraseProc)
  418. {
  419.     spriteWorldP->eraseDrawProc = eraseProc;
  420. }
  421.  
  422.  
  423. ///--------------------------------------------------------------------------------------
  424. //    SWSetSpriteWorldDrawProc
  425. ///--------------------------------------------------------------------------------------
  426.  
  427. SW_FUNC void SWSetSpriteWorldDrawProc(
  428.     SpriteWorldPtr spriteWorldP,
  429.     WorldDrawProcPtr drawProc)
  430. {
  431.     spriteWorldP->screenDrawProc = drawProc;
  432. }
  433.  
  434.  
  435. ///--------------------------------------------------------------------------------------
  436. //    SWStdWorldDrawProc
  437. ///--------------------------------------------------------------------------------------
  438.  
  439. SW_FUNC void SWStdWorldDrawProc(
  440.     FramePtr srcFrameP,
  441.     FramePtr dstFrameP,
  442.     Rect* drawRect)
  443. {
  444.     CopyBits((BitMapPtr)srcFrameP->framePix.pixMapP, (BitMapPtr)dstFrameP->framePix.pixMapP,
  445.                 drawRect, drawRect, srcCopy, NULL);
  446. }
  447.  
  448.  
  449. ///--------------------------------------------------------------------------------------
  450. //    SWUpdateSpriteWorld
  451. ///--------------------------------------------------------------------------------------
  452.  
  453. SW_FUNC void SWUpdateSpriteWorld(
  454.     SpriteWorldPtr spriteWorldP)
  455. {
  456.     register SpriteLayerPtr curSpriteLayerP;
  457.     register SpritePtr curSpriteP;
  458.     Rect rgnRect;
  459.  
  460.         // the current port should the one in which we are drawing    
  461.     SetPort(spriteWorldP->loadFrameP->framePort.monoGrafP);
  462.  
  463.     (*spriteWorldP->eraseDrawProc)(spriteWorldP->backFrameP,
  464.                                 spriteWorldP->loadFrameP,
  465.                                 &spriteWorldP->loadFrameP->frameRect);
  466.  
  467.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  468.  
  469.         // iterate through the layers in this world
  470.     while (curSpriteLayerP != NULL)
  471.     {
  472.         curSpriteP = curSpriteLayerP->headSpriteP;
  473.  
  474.             // iterate through the sprites in this layer
  475.         while (curSpriteP != NULL)
  476.         {
  477.             if (curSpriteP->isVisible)
  478.             {
  479.                 if (curSpriteP->curFrameP->maskRgn != NULL)
  480.                 {
  481.                     rgnRect = (**curSpriteP->curFrameP->maskRgn).rgnBBox;
  482.  
  483.                         // move the mask region to the new sprite location
  484.                     OffsetRgn(
  485.                         curSpriteP->curFrameP->maskRgn,
  486.                         (curSpriteP->destFrameRect.left - rgnRect.left) +
  487.                         curSpriteP->curFrameP->offsetPoint.h,
  488.                         (curSpriteP->destFrameRect.top - rgnRect.top) +
  489.                         curSpriteP->curFrameP->offsetPoint.v);
  490.                 }
  491.  
  492.                     // copy the sprite image onto the back drop piece
  493.                 (*curSpriteP->frameDrawProc)(curSpriteP->curFrameP,
  494.                                             spriteWorldP->loadFrameP,
  495.                                             &curSpriteP->curFrameP->frameRect,
  496.                                             &curSpriteP->destFrameRect);
  497.             }
  498.  
  499.             curSpriteP = curSpriteP->nextSpriteP;
  500.         }
  501.  
  502.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  503.     }
  504.  
  505.             // the current port should the one in which we are drawing    
  506.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  507.  
  508.     (*spriteWorldP->screenDrawProc)(spriteWorldP->loadFrameP,
  509.                                     spriteWorldP->windowFrameP,
  510.                                     &spriteWorldP->windowFrameP->frameRect);
  511. }
  512.  
  513.  
  514. ///--------------------------------------------------------------------------------------
  515. //    SWProcessSpriteWorld
  516. ///--------------------------------------------------------------------------------------
  517.  
  518. SW_FUNC void SWProcessSpriteWorld(
  519.     SpriteWorldPtr spriteWorldP)
  520. {
  521.     register SpriteLayerPtr curSpriteLayerP;
  522.     SpriteLayerPtr nextSpriteLayerP;
  523.     register SpritePtr curSpriteP;
  524.     SpritePtr nextSpriteP;
  525.     register FramePtr oldFrameP, newFrameP;
  526.     Point spritePoint, oldPoint;
  527.     short horizOffset, vertOffset;
  528.  
  529.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  530.  
  531.         // iterate through the layers in this world
  532.     while (curSpriteLayerP != NULL)
  533.     {
  534.         nextSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  535.         curSpriteP = curSpriteLayerP->headSpriteP;
  536.  
  537.             // iterate through the sprites in this layer
  538.         while (curSpriteP != NULL)
  539.         {
  540.             nextSpriteP = curSpriteP->nextSpriteP;
  541.  
  542.                 // is it time to advance the sprite’s frame?
  543.             if (curSpriteP->frameTimeTask.hasTaskFired)
  544.             {
  545.                 curSpriteP->curFrameIndex += curSpriteP->frameAdvance;
  546.  
  547.                 if (curSpriteP->curFrameIndex < curSpriteP->firstFrameIndex)
  548.                 {
  549.                         // wrap to the last frame
  550.                     curSpriteP->curFrameIndex = curSpriteP->lastFrameIndex;
  551.                 }
  552.                 else if (curSpriteP->curFrameIndex > curSpriteP->lastFrameIndex)
  553.                 {
  554.                         // wrap to the first frame
  555.                     curSpriteP->curFrameIndex = curSpriteP->firstFrameIndex;
  556.                 }
  557.  
  558.                     // get new frame
  559.                 newFrameP =    curSpriteP->frameArray[curSpriteP->curFrameIndex];
  560.  
  561.                     // is there a frame callback?
  562.                 if (curSpriteP->frameChangeProc != NULL)
  563.                 {
  564.                         // call it
  565.                     (*curSpriteP->frameChangeProc)(curSpriteP, newFrameP,
  566.                             &curSpriteP->curFrameIndex);
  567.  
  568.                         // make sure the new frame index is in range
  569.                     if (curSpriteP->curFrameIndex < 0)
  570.                     {
  571.                         curSpriteP->curFrameIndex = 0;
  572.                     }
  573.                     else if (curSpriteP->curFrameIndex >= curSpriteP->maxFrames)
  574.                     {
  575.                         curSpriteP->curFrameIndex = curSpriteP->maxFrames - 1;
  576.                     }
  577.                 }
  578.  
  579.                     // change the frame
  580.                 newFrameP =    curSpriteP->frameArray[curSpriteP->curFrameIndex];
  581.  
  582.                     // has the frame actually changed?
  583.                 if (curSpriteP->curFrameP != newFrameP)
  584.                 {
  585.                     oldFrameP = curSpriteP->curFrameP;
  586.                     curSpriteP->curFrameP = newFrameP;
  587.  
  588.                     horizOffset = (curSpriteP->destFrameRect.left - newFrameP->frameRect.left);
  589.                     vertOffset = (curSpriteP->destFrameRect.top - newFrameP->frameRect.top);
  590.  
  591.                     curSpriteP->destFrameRect = newFrameP->frameRect;
  592.  
  593.                     curSpriteP->destFrameRect.left += horizOffset;
  594.                     curSpriteP->destFrameRect.right += horizOffset;
  595.                     curSpriteP->destFrameRect.top += vertOffset;
  596.                     curSpriteP->destFrameRect.bottom += vertOffset;
  597.  
  598.                     curSpriteP->needsToBeDrawn = true;
  599.                 }
  600.  
  601.                 if (curSpriteP->frameTimeInterval > 0)
  602.                 {
  603.                     curSpriteP->frameTimeTask.hasTaskFired = false;
  604.  
  605.                         // reset the time till next frame
  606.                     PrimeTime((QElemPtr)&curSpriteP->frameTimeTask, curSpriteP->frameTimeInterval);
  607.                 }
  608.             }
  609.  
  610.                 // is it time to move the sprite?
  611.             if (curSpriteP->moveTimeTask.hasTaskFired)
  612.             {
  613.                     // is there a movement callback?
  614.                 if (curSpriteP->spriteMoveProc != NULL)
  615.                 {
  616.                     oldPoint = *(Point*)&(curSpriteP->destFrameRect);
  617.                     spritePoint = oldPoint;
  618.                     spritePoint.h += curSpriteP->horizMoveDelta;
  619.                     spritePoint.v += curSpriteP->vertMoveDelta;
  620.  
  621.                         // call it
  622.                     (*curSpriteP->spriteMoveProc)(curSpriteP, &spritePoint);
  623.  
  624.                     if ((spritePoint.h != oldPoint.h) || (spritePoint.v != oldPoint.v))
  625.                     {
  626.                         curSpriteP->destFrameRect.right  = (curSpriteP->destFrameRect.right -
  627.                                                             curSpriteP->destFrameRect.left) +
  628.                                                             spritePoint.h;
  629.                         curSpriteP->destFrameRect.bottom = (curSpriteP->destFrameRect.bottom -
  630.                                                             curSpriteP->destFrameRect.top) +
  631.                                                             spritePoint.v;
  632.                         curSpriteP->destFrameRect.left = spritePoint.h;
  633.                         curSpriteP->destFrameRect.top = spritePoint.v;
  634.  
  635.                         curSpriteP->needsToBeDrawn = true;
  636.                     }
  637.                 }
  638.                 else if ((curSpriteP->horizMoveDelta != 0) || (curSpriteP->vertMoveDelta != 0))
  639.                 {
  640.                         // offset destination rect (way faster than OffsetRect)
  641.                     curSpriteP->destFrameRect.top += curSpriteP->vertMoveDelta;
  642.                     curSpriteP->destFrameRect.left += curSpriteP->horizMoveDelta;
  643.                     curSpriteP->destFrameRect.bottom += curSpriteP->vertMoveDelta;
  644.                     curSpriteP->destFrameRect.right += curSpriteP->horizMoveDelta;
  645.  
  646.                     curSpriteP->needsToBeDrawn = true;
  647.                 }
  648.  
  649.                 if (curSpriteP->moveTimeInterval > 0)
  650.                 {
  651.                     curSpriteP->moveTimeTask.hasTaskFired = false;
  652.  
  653.                         // reset the time till next move
  654.                     PrimeTime((QElemPtr)&curSpriteP->moveTimeTask,
  655.                             curSpriteP->moveTimeInterval);
  656.                 }
  657.             }
  658.  
  659.             if (nextSpriteP != NULL)
  660.             {
  661.                 curSpriteP = nextSpriteP;
  662.             }
  663.             else
  664.             {
  665.                 curSpriteP = curSpriteP->nextSpriteP;
  666.             }
  667.         }
  668.  
  669.         if (nextSpriteLayerP != NULL)
  670.         {
  671.             curSpriteLayerP = nextSpriteLayerP;    
  672.         }
  673.         else
  674.         {
  675.             curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  676.         }
  677.     }
  678. }
  679.  
  680.  
  681. ///--------------------------------------------------------------------------------------
  682. //    SWAnimateSpriteWorld
  683. ///--------------------------------------------------------------------------------------
  684.  
  685. SW_FUNC void SWAnimateSpriteWorld(
  686.     SpriteWorldPtr spriteWorldP)
  687. {
  688.     register SpriteLayerPtr curSpriteLayerP;
  689.     register SpritePtr curSpriteP;
  690.     SpritePtr headActiveSpriteP = NULL;
  691.     SpritePtr curActiveSpriteP = NULL;
  692.  
  693.  
  694.     //-----------------erase the sprites--------------------
  695.  
  696.         // the current port should the one in which we are drawing    
  697.     SetPort(spriteWorldP->loadFrameP->framePort.monoGrafP);
  698.  
  699.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  700.  
  701.         // iterate through the layers in this world
  702.     while (curSpriteLayerP != NULL)
  703.     {
  704.         curSpriteP = curSpriteLayerP->headSpriteP;
  705.  
  706.             // iterate through the sprites in this layer
  707.         while (curSpriteP != NULL)
  708.         {
  709.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  710.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  711.             {
  712.                 if (headActiveSpriteP == NULL)
  713.                     headActiveSpriteP = curSpriteP;
  714.  
  715.                 if (curActiveSpriteP != NULL)
  716.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  717.  
  718.                 curActiveSpriteP = curSpriteP;
  719.  
  720.                     // union last rect and current rect
  721.                     // this way is much faster than UnionRect
  722.                 curSpriteP->deltaFrameRect.top =
  723.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  724.                 curSpriteP->deltaFrameRect.left =
  725.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  726.                 curSpriteP->deltaFrameRect.bottom =
  727.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  728.                 curSpriteP->deltaFrameRect.right =
  729.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  730.  
  731.                 {
  732.                     short temp;
  733.  
  734.                         // align the left edge to long word boundary
  735.                     curSpriteP->deltaFrameRect.left &=
  736.                             (spriteWorldP->loadFrameP->leftAlignFactor);
  737.  
  738.                         // align the right edge to long word boundary
  739.                     temp = curSpriteP->deltaFrameRect.right &
  740.                         spriteWorldP->loadFrameP->rightAlignFactor;
  741.                     if (temp != 0)
  742.                     {
  743.                         curSpriteP->deltaFrameRect.right +=
  744.                                 (spriteWorldP->loadFrameP->rightAlignFactor + 1) - temp;
  745.                     }
  746.  
  747.                         // align the left edge to long word boundary
  748.                     curSpriteP->oldFrameRect.left &=
  749.                         (spriteWorldP->loadFrameP->leftAlignFactor);
  750.  
  751.                         // align the right edge to long word boundary
  752.                     temp = curSpriteP->oldFrameRect.right &
  753.                         spriteWorldP->loadFrameP->rightAlignFactor;
  754.                     if (temp != 0)
  755.                     {
  756.                         curSpriteP->oldFrameRect.right +=
  757.                             (spriteWorldP->loadFrameP->rightAlignFactor + 1) - temp;
  758.                     }
  759.                 }
  760.  
  761.                     // copy the back drop piece
  762.                 (*spriteWorldP->eraseDrawProc)(
  763.                         spriteWorldP->backFrameP,
  764.                         spriteWorldP->loadFrameP,
  765.                         &curSpriteP->oldFrameRect);
  766.             }
  767.  
  768.             curSpriteP = curSpriteP->nextSpriteP;
  769.         }
  770.  
  771.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  772.     }
  773.  
  774.     if (curActiveSpriteP != NULL)
  775.             curActiveSpriteP->nextActiveSpriteP = NULL;
  776.  
  777.  
  778.     //-----------------draw the sprites--------------------
  779.  
  780.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  781.  
  782.         // iterate through the layers in this world
  783.     while (curSpriteLayerP != NULL)
  784.     {
  785.         curSpriteP = curSpriteLayerP->headSpriteP;
  786.  
  787.             // iterate through the sprites in this layer
  788.         while (curSpriteP != NULL)
  789.         {
  790.             if (curSpriteP->isVisible)
  791.             {
  792.                 if (curSpriteP->needsToBeDrawn)
  793.                 {
  794.                     if (curSpriteP->curFrameP->maskRgn != NULL)
  795.                     {
  796.                         Rect rgnRect = (**curSpriteP->curFrameP->maskRgn).rgnBBox;
  797.     
  798.                             // move the mask region to the new sprite location
  799.                         OffsetRgn(
  800.                             curSpriteP->curFrameP->maskRgn,
  801.                             (curSpriteP->destFrameRect.left - rgnRect.left) +
  802.                             curSpriteP->curFrameP->offsetPoint.h,
  803.                             (curSpriteP->destFrameRect.top - rgnRect.top) +
  804.                             curSpriteP->curFrameP->offsetPoint.v);
  805.                     }
  806.  
  807.                         // copy the sprite image onto the back drop piece
  808.                     (*curSpriteP->frameDrawProc)(
  809.                             curSpriteP->curFrameP,
  810.                             spriteWorldP->loadFrameP,
  811.                             &curSpriteP->curFrameP->frameRect,
  812.                             &curSpriteP->destFrameRect);
  813.                 }
  814.                 else
  815.                 {
  816.                     SWCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  817.                 }
  818.             }
  819.  
  820.             curSpriteP = curSpriteP->nextSpriteP;
  821.         }
  822.  
  823.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  824.     }
  825.  
  826.  
  827.     //-----------------update the screen--------------------
  828.  
  829.         // the current port should the one in which we are drawing    
  830.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  831.  
  832.     curSpriteP = headActiveSpriteP;
  833.  
  834.         // iterate through the sprites in this layer
  835.     while (curSpriteP != NULL)
  836.     {
  837.             // copy the backdrop+sprite piece from the loader to the screen
  838.         (*spriteWorldP->screenDrawProc)(
  839.                 spriteWorldP->loadFrameP,
  840.                 spriteWorldP->windowFrameP,
  841.                 &curSpriteP->deltaFrameRect);
  842.  
  843.             // set the delta and last rect to the current rect
  844.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  845.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  846.  
  847.             // this sprite no longer needs to be drawn
  848.         curSpriteP->needsToBeDrawn = false;
  849.         curSpriteP->needsToBeErased = false;
  850.  
  851.         curSpriteP = curSpriteP->nextActiveSpriteP;
  852.     }
  853. }
  854.  
  855.  
  856. ///--------------------------------------------------------------------------------------
  857. //    SWFastAnimateSpriteWorld
  858. ///--------------------------------------------------------------------------------------
  859.  
  860. SW_FUNC void SWFastAnimateSpriteWorld(
  861.     SpriteWorldPtr spriteWorldP)
  862. {
  863.     register SpriteLayerPtr curSpriteLayerP;
  864.     register SpritePtr curSpriteP;
  865.     SpritePtr headActiveSpriteP = NULL;
  866.     SpritePtr curActiveSpriteP = NULL;
  867. #if !SW_PPC
  868.     //char mmuMode;
  869.     SInt8    mmuMode;
  870.  
  871.         // if we are already in 32 bit mode, then we don't have to incur the
  872.         // overhead of calling SwapMMUMode. if we are in 24 bit mode, we incur
  873.         // a neglible hit by checking before the swap.
  874.     if (gSWmmuMode != true32b)
  875.     {
  876.             // change to 32-bit addressing mode to access video memory
  877.             // the previous addressing mode is returned in mmuMode for restoring later
  878.         mmuMode = true32b;
  879.         SwapMMUMode(&mmuMode);
  880.     }
  881. #endif
  882.  
  883.     //-----------------erase the sprites--------------------
  884.  
  885.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  886.  
  887.         // iterate through the layers in this world
  888.     while (curSpriteLayerP != NULL)
  889.     {
  890.         curSpriteP = curSpriteLayerP->headSpriteP;
  891.  
  892.             // iterate through the sprites in this layer
  893.         while (curSpriteP != NULL)
  894.         {
  895.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  896.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  897.             {
  898.                 if (headActiveSpriteP == NULL)
  899.                     headActiveSpriteP = curSpriteP;
  900.  
  901.                 if (curActiveSpriteP != NULL)
  902.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  903.  
  904.                 curActiveSpriteP = curSpriteP;
  905.  
  906.                     // union last rect and current rect
  907.                     // this way is much faster than UnionRect
  908.                 curSpriteP->deltaFrameRect.top =
  909.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  910.                 curSpriteP->deltaFrameRect.left =
  911.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  912.                 curSpriteP->deltaFrameRect.bottom =
  913.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  914.                 curSpriteP->deltaFrameRect.right =
  915.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  916.  
  917.                 {
  918.                     short temp;
  919.  
  920.                         // align the left edge to long word boundary
  921.                     curSpriteP->deltaFrameRect.left &= kLeftAlignFactor;
  922.  
  923.                         // align the right edge to long word boundary
  924.                     temp = curSpriteP->deltaFrameRect.right & kRightAlignFactor;
  925.                     if (temp != 0)
  926.                     {
  927.                         curSpriteP->deltaFrameRect.right += (kRightAlignFactor+1) - temp;
  928.                     }
  929.  
  930.                         // align the left edge to long word boundary
  931.                     curSpriteP->oldFrameRect.left &= kLeftAlignFactor;
  932.  
  933.                         // align the right edge to long word boundary
  934.                     temp = curSpriteP->oldFrameRect.right & kRightAlignFactor;
  935.                     if (temp != 0)
  936.                     {
  937.                         curSpriteP->oldFrameRect.right += (kRightAlignFactor+1) - temp;
  938.                     }
  939.                 }
  940.  
  941.                     // copy the back drop piece
  942.                 (*spriteWorldP->eraseDrawProc)(
  943.                         spriteWorldP->backFrameP,
  944.                         spriteWorldP->loadFrameP,
  945.                         &curSpriteP->oldFrameRect);
  946.             }
  947.  
  948.             curSpriteP = curSpriteP->nextSpriteP;
  949.         }
  950.  
  951.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  952.     }
  953.  
  954.     if (curActiveSpriteP != NULL)
  955.             curActiveSpriteP->nextActiveSpriteP = NULL;
  956.  
  957.  
  958.     //-----------------draw the sprites--------------------
  959.  
  960.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  961.  
  962.         // iterate through the layers in this world
  963.     while (curSpriteLayerP != NULL)
  964.     {
  965.         curSpriteP = curSpriteLayerP->headSpriteP;
  966.  
  967.             // iterate through the sprites in this layer
  968.         while (curSpriteP != NULL)
  969.         {
  970.             if (curSpriteP->isVisible)
  971.             {
  972.                 if (curSpriteP->needsToBeDrawn)
  973.                 {
  974.                         // copy the sprite image onto the back drop piece
  975.                     (*curSpriteP->frameDrawProc)(
  976.                             curSpriteP->curFrameP,
  977.                             spriteWorldP->loadFrameP,
  978.                             &curSpriteP->curFrameP->frameRect,
  979.                             &curSpriteP->destFrameRect);
  980.                 }
  981.                 else
  982.                 {
  983.                     SWFastCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  984.                 }
  985.             }
  986.  
  987.             curSpriteP = curSpriteP->nextSpriteP;
  988.         }
  989.  
  990.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  991.     }
  992.  
  993.  
  994.     //-----------------update the screen--------------------
  995.  
  996.     curSpriteP = headActiveSpriteP;
  997.  
  998.         // iterate through the sprites in this layer
  999.     while (curSpriteP != NULL)
  1000.     {
  1001.             // copy the backdrop+sprite piece from the loader to the screen
  1002.         (*spriteWorldP->screenDrawProc)(
  1003.                 spriteWorldP->loadFrameP,
  1004.                 spriteWorldP->windowFrameP,
  1005.                 &curSpriteP->deltaFrameRect);
  1006.  
  1007.             // set the delta and last rect to the current rect
  1008.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  1009.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  1010.  
  1011.             // this sprite no longer needs to be drawn
  1012.         curSpriteP->needsToBeDrawn = false;
  1013.         curSpriteP->needsToBeErased = false;
  1014.  
  1015.         curSpriteP = curSpriteP->nextActiveSpriteP;
  1016.     }
  1017.  
  1018. #if !SW_PPC
  1019.     if (gSWmmuMode != true32b)
  1020.     {
  1021.         SwapMMUMode(&mmuMode);
  1022.     }
  1023. #endif
  1024. }
  1025.  
  1026.  
  1027. ///--------------------------------------------------------------------------------------
  1028. //    SWBlastAnimateSpriteWorld
  1029. ///--------------------------------------------------------------------------------------
  1030.  
  1031. SW_FUNC void SWBlastAnimateSpriteWorld(
  1032.     SpriteWorldPtr spriteWorldP)
  1033. {
  1034.     register SpriteLayerPtr curSpriteLayerP;
  1035.     register SpritePtr curSpriteP;
  1036.     SpritePtr headActiveSpriteP = NULL;
  1037.     SpritePtr curActiveSpriteP = NULL;
  1038. #if !SW_PPC
  1039.     SInt8 mmuMode;
  1040.  
  1041.         // if we are already in 32 bit mode, then we don't have to incur the
  1042.         // overhead of calling SwapMMUMode. if we are in 24 bit mode, we incur
  1043.         // a neglible hit by checking before the swap.
  1044.     if (gSWmmuMode != true32b)
  1045.     {
  1046.             // change to 32-bit addressing mode to access video memory
  1047.             // the previous addressing mode is returned in mmuMode for restoring later
  1048.         mmuMode = true32b;
  1049.         SwapMMUMode(&mmuMode);
  1050.     }
  1051. #endif
  1052.  
  1053.     //-----------------erase the sprites--------------------
  1054.  
  1055.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  1056.  
  1057.         // iterate through the layers in this world
  1058.     while (curSpriteLayerP != NULL)
  1059.     {
  1060.         curSpriteP = curSpriteLayerP->headSpriteP;
  1061.  
  1062.             // iterate through the sprites in this layer
  1063.         while (curSpriteP != NULL)
  1064.         {
  1065.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  1066.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  1067.             {
  1068.                 if (headActiveSpriteP == NULL)
  1069.                     headActiveSpriteP = curSpriteP;
  1070.  
  1071.                 if (curActiveSpriteP != NULL)
  1072.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  1073.  
  1074.                 curActiveSpriteP = curSpriteP;
  1075.  
  1076.                     // union last rect and current rect
  1077.                     // this way is much faster than UnionRect
  1078.                 curSpriteP->deltaFrameRect.top =
  1079.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  1080.                 curSpriteP->deltaFrameRect.left =
  1081.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  1082.                 curSpriteP->deltaFrameRect.bottom =
  1083.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  1084.                 curSpriteP->deltaFrameRect.right =
  1085.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  1086.  
  1087.                 {
  1088.                     short temp;
  1089.  
  1090.                         // align the left edge to long word boundary
  1091.                     curSpriteP->deltaFrameRect.left &= kLeftAlignFactor;
  1092.  
  1093.                         // align the right edge to long word boundary
  1094.                     temp = curSpriteP->deltaFrameRect.right & kRightAlignFactor;
  1095.                     if (temp != 0)
  1096.                     {
  1097.                         curSpriteP->deltaFrameRect.right += (kRightAlignFactor+1) - temp;
  1098.                     }
  1099.  
  1100.                         // align the left edge to long word boundary
  1101.                     curSpriteP->oldFrameRect.left &= kLeftAlignFactor;
  1102.  
  1103.                         // align the right edge to long word boundary
  1104.                     temp = curSpriteP->oldFrameRect.right & kRightAlignFactor;
  1105.                     if (temp != 0)
  1106.                     {
  1107.                         curSpriteP->oldFrameRect.right += (kRightAlignFactor+1) - temp;
  1108.                     }
  1109.                 }
  1110.  
  1111.                     // copy the back drop piece
  1112.                 BlitPixieWorldDrawProc(
  1113.                         spriteWorldP->backFrameP,
  1114.                         spriteWorldP->loadFrameP,
  1115.                         &curSpriteP->oldFrameRect);
  1116.             }
  1117.  
  1118.             curSpriteP = curSpriteP->nextSpriteP;
  1119.         }
  1120.  
  1121.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  1122.     }
  1123.  
  1124.     if (curActiveSpriteP != NULL)
  1125.             curActiveSpriteP->nextActiveSpriteP = NULL;
  1126.  
  1127.  
  1128.     //-----------------draw the sprites--------------------
  1129.  
  1130.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  1131.  
  1132.         // iterate through the layers in this world
  1133.     while (curSpriteLayerP != NULL)
  1134.     {
  1135.         curSpriteP = curSpriteLayerP->headSpriteP;
  1136.  
  1137.             // iterate through the sprites in this layer
  1138.         while (curSpriteP != NULL)
  1139.         {
  1140.             if (curSpriteP->isVisible)
  1141.             {
  1142.                 if (curSpriteP->needsToBeDrawn)
  1143.                 {
  1144.                             // jump into the compiled mask code
  1145.                     (*curSpriteP->frameDrawProc)(
  1146.                             curSpriteP->curFrameP,
  1147.                             spriteWorldP->loadFrameP,
  1148.                             &curSpriteP->curFrameP->frameRect,
  1149.                             &curSpriteP->destFrameRect);
  1150.                 }
  1151.                 else
  1152.                 {
  1153.                     SWFastCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  1154.                 }
  1155.             }
  1156.  
  1157.             curSpriteP = curSpriteP->nextSpriteP;
  1158.         }
  1159.  
  1160.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  1161.     }
  1162.  
  1163.  
  1164.     //-----------------update the screen--------------------
  1165.  
  1166.     curSpriteP = headActiveSpriteP;
  1167.  
  1168.         // iterate through the sprites in this layer
  1169.     while (curSpriteP != NULL)
  1170.     {
  1171.             // copy the backdrop+sprite piece from the loader to the screen
  1172.         BlitPixieWorldDrawProc(
  1173.                 spriteWorldP->loadFrameP,
  1174.                 spriteWorldP->windowFrameP,
  1175.                 &curSpriteP->deltaFrameRect);
  1176.  
  1177.             // set the delta and last rect to the current rect
  1178.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  1179.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  1180.  
  1181.             // this sprite no longer needs to be drawn
  1182.         curSpriteP->needsToBeDrawn = false;
  1183.         curSpriteP->needsToBeErased = false;
  1184.  
  1185.         curSpriteP = curSpriteP->nextActiveSpriteP;
  1186.     }
  1187.  
  1188. #if !SW_PPC
  1189.     if (gSWmmuMode != true32b)
  1190.     {
  1191.         SwapMMUMode(&mmuMode);
  1192.     }
  1193. #endif
  1194. }
  1195.  
  1196.  
  1197. ///--------------------------------------------------------------------------------------
  1198. //    SWCheckIdleSpriteOverlap
  1199. ///--------------------------------------------------------------------------------------
  1200.  
  1201. static void SWCheckIdleSpriteOverlap(
  1202.     SpriteWorldPtr spriteWorldP,
  1203.     register SpritePtr idleSpriteP,
  1204.     SpritePtr headActiveSpriteP)
  1205. {
  1206.     register SpritePtr activeSpriteP;
  1207.     RgnHandle maskRgn = idleSpriteP->curFrameP->maskRgn;
  1208.  
  1209.     activeSpriteP = headActiveSpriteP;
  1210.  
  1211.         // iterate through the active sprites
  1212.     while (activeSpriteP != NULL)
  1213.     {
  1214.             // do the sprites overlap?
  1215.         if ((idleSpriteP->destFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
  1216.              (idleSpriteP->destFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
  1217.              (idleSpriteP->destFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
  1218.              (idleSpriteP->destFrameRect.right > activeSpriteP->deltaFrameRect.left))
  1219.         {
  1220.             Rect srcSectRect, dstSectRect;
  1221.  
  1222.             if (maskRgn != NULL)
  1223.             {
  1224.                     // move the mask region to the new sprite location
  1225.                 OffsetRgn(
  1226.                     maskRgn,
  1227.                     (idleSpriteP->destFrameRect.left - (**maskRgn).rgnBBox.left) +
  1228.                     idleSpriteP->curFrameP->offsetPoint.h,
  1229.                     (idleSpriteP->destFrameRect.top - (**maskRgn).rgnBBox.top) +
  1230.                     idleSpriteP->curFrameP->offsetPoint.v);
  1231.  
  1232.                 maskRgn = NULL;
  1233.             }
  1234.  
  1235.                 // calculate the intersection between the idle sprite's destination
  1236.                 // rect, and the active sprite's old rect
  1237.             dstSectRect.left =
  1238.                     SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
  1239.             dstSectRect.top =
  1240.                     SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
  1241.             dstSectRect.right =
  1242.                     SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
  1243.             dstSectRect.bottom =
  1244.                     SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
  1245.  
  1246.             srcSectRect = dstSectRect;
  1247.  
  1248.             srcSectRect.left -= idleSpriteP->destFrameRect.left;
  1249.             srcSectRect.right -= idleSpriteP->destFrameRect.left;
  1250.             srcSectRect.top -= idleSpriteP->destFrameRect.top;
  1251.             srcSectRect.bottom -= idleSpriteP->destFrameRect.top;
  1252.  
  1253.                 // copy a piece of the sprite image onto the back drop piece
  1254.             (*idleSpriteP->frameDrawProc)(
  1255.                     idleSpriteP->curFrameP,
  1256.                     spriteWorldP->loadFrameP,
  1257.                     &srcSectRect,
  1258.                     &dstSectRect);
  1259.         }
  1260.  
  1261.         activeSpriteP = activeSpriteP->nextActiveSpriteP;
  1262.     }
  1263. }
  1264.  
  1265.  
  1266. ///--------------------------------------------------------------------------------------
  1267. //    SWFastCheckIdleSpriteOverlap
  1268. ///--------------------------------------------------------------------------------------
  1269.  
  1270. static void SWFastCheckIdleSpriteOverlap(
  1271.     SpriteWorldPtr spriteWorldP,
  1272.     register SpritePtr idleSpriteP,
  1273.     SpritePtr headActiveSpriteP)
  1274. {
  1275.     register SpritePtr activeSpriteP = headActiveSpriteP;
  1276.  
  1277.         // iterate through the active sprites
  1278.     while (activeSpriteP != NULL)
  1279.     {
  1280.             // do the sprites overlap?
  1281.         if ((idleSpriteP->destFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
  1282.              (idleSpriteP->destFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
  1283.              (idleSpriteP->destFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
  1284.              (idleSpriteP->destFrameRect.right > activeSpriteP->deltaFrameRect.left))
  1285.         {
  1286.             Rect srcSectRect, dstSectRect;
  1287.  
  1288.                 // calculate the intersection between the idle sprite's destination
  1289.                 // rect, and the active sprite's old rect
  1290.             dstSectRect.left =
  1291.                     SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
  1292.             dstSectRect.top =
  1293.                     SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
  1294.             dstSectRect.right =
  1295.                     SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
  1296.             dstSectRect.bottom =
  1297.                     SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
  1298.  
  1299.             srcSectRect = dstSectRect;
  1300.  
  1301.             srcSectRect.left -= idleSpriteP->destFrameRect.left;
  1302.             srcSectRect.right -= idleSpriteP->destFrameRect.left;
  1303.             srcSectRect.top -= idleSpriteP->destFrameRect.top;
  1304.             srcSectRect.bottom -= idleSpriteP->destFrameRect.top;
  1305.  
  1306.                 // copy a piece of the sprite image onto the back drop piece
  1307.             (*idleSpriteP->frameDrawProc)(
  1308.                     idleSpriteP->curFrameP,
  1309.                     spriteWorldP->loadFrameP,
  1310.                     &srcSectRect,
  1311.                     &dstSectRect);
  1312.         }
  1313.  
  1314.         activeSpriteP = activeSpriteP->nextActiveSpriteP;
  1315.     }
  1316. }
  1317.  
  1318.  
  1319.